#!/bin/bash

# /usr/local/bin/lstbox
# 2020.9.25 by dewan
# modify at 2020.11.13 2020.12.31

usage() {

echo "
SYNOPSIS
	lstbox <tbox_num> [tbox_num ..] [sh|cat|stat|queues|view|list|clean]

DESCRIPTION

	$ lstbox <tbox_num> [tbox_num ..]  # Show basic info ..
	
	$ lstbox <tbox_num> sh		   # ssh to ..
	
	no-passwd login, if you do first:  
		$ echo 'your_testbox_passwd' > ~/.tbox_passwd
			
	$ lstbox <tbox_num> cat		   # view serial log ..
		
	$ lstbox <tbox_num> list	   # list all testboxes

	$ lstbox <tbox_num> ready	   # list nearly requesting testboxes
	
	$ lstbox <tbox_num> reset	   # reboot if you carry it

	$ lstbox <tbox_num> clean	   # clean hostname's ready job

	$ lstbox <tbox_num> register	   # register to scheduler    

	$ lstbox <tbox_num> host-file	   # submit host-file to testbox    

	$ lstbox <tbox_num> borrow	   # submit borrow-1d to testbox    
	
	no-passwd do reset or cat cmd-opt, do it first:
		$ ssh-copy-id -p 2022 ibmc-mgnt	
	
"
}

servers_file=/etc/servers.info
registed_file=/etc/mac2host
#dnsmasq_file=/etc/compass-ci/dnsmasq/lease_dir/dnsmasq.leases
passwd_file=${HOME}/.tbox_passwd
serial_log_dir=/srv/cci/serial/logs

for file in {"$servers_file","$registed_file"}
do
	[ -f $file ] || {
		echo "File: $file not found, please @lab_maintainer!"
		exit
	}
done

ParamCheck() {
	# <= tbox_num

	[[ "$tbox_num" =~ [abcd][0-9]+ ]] || {
		echo "input: $tbox_num, paramter error!"
		exit
	}
}

Basic() {
	# <= tbox_num
	# <= ParamCheck
	# <= redis-cli
	# <= es-find
	# <= redis_register_hostname
	
	ParamCheck	
	tmp=$(grep ${tbox_num}$ $registed_file) 
	if [ -z "$tmp" ];then
		echo "failed: $tbox_num not found in $registed_file, please check!"
		exit
	fi
	host_name=$(echo "$tmp" | awk '{print $3}')
	host_num=$(echo "$tmp" | awk '{print $1}')
	host_mac=$(echo "$tmp" | awk '{print $2}'|sed 's/-/:/g')
	host_owner=$(grep $host_num $servers_file | awk '{print $7}')

	tmp2=$(redis-cli hget sched/tbox_wtmp $host_name)

	host_ip=$(echo "$tmp2" | jq -r '.ip')
	[ "null" == "$host_ip" ] && {
		host_ip=$(arp -n | grep "$host_mac" | awk '{print $1}')
	}	

	host_status=$(echo "$tmp2" | jq -r '.state')
	job_id=$(echo "$tmp2" | jq -r '.job_id' )
	job_start_time=$(echo "$tmp2" | jq -r '.time')

	if command -v es-find > /dev/null ;then
		[ -n "$job_id" ] && tmp3=$(es-find id="$job_id")
		#job_user_email=$(echo "$tmp3" | grep my_email | awk -F'"' '{print $4}')
		job_user_account=$(echo "$tmp3" | grep my_account | awk -F'"' '{print $4}')
		job_name=$(echo "$tmp3" | grep \"suite\" | awk -F'"' '{print $4}')
	else
		echo -e "command es-find not found, please check environment variables!\n"
	fi

	#echo -e "host_name: \033[32m$host_name\033[0m"
	echo "host_name: $host_name"
	echo "host_num: $host_num"
	echo "host_mac: $host_mac"
	echo "host_owner: $host_owner"
	[ -n "$(redis_register_hostname)" ] || return
	[ -n "$host_status" ] || return
	if [ $host_status = "running" ] ; then 
		echo -e "Active: \033[32m($host_status)\033[0m"
	else
		echo -e "Active: \033[33m($host_status)\033[0m"
	fi
	
	[ $host_status = "rebooting" ] && return
	echo "host_ip: $host_ip"
	echo "job_id: $job_id"
	echo -e "job_name: \033[36m$job_name\033[0m"
	echo "job_start_time: $job_start_time"
	#echo "job_user_email: $job_user_email"
	echo "job_user_account: $job_user_account"
}

redis_register_hostname()
{	
	# <= host_mac
	local mac register_hostname
	mac=$(echo "$host_mac" | tr : -)
	register_hostname=$(redis-cli hget sched/mac2host "$mac")
	echo "$register_hostname"
}

redis_register_queues()
{	
	# <= host_name
	local register_queues
	register_queues=$(redis-cli hget sched/host2queues "$host_name")
	echo "$register_queues"
}

etcd_queue_jobs()
{
	local key queue_jobs
	key=$(echo "$(redis_register_queues)" | awk -F, '{print $1}')
	queue_jobs=$(etcdctl get --prefix "/queues/sched/ready/$key/")	
	echo "$queue_jobs"
}

echo_register_queues()
{
	echo "pub_queues: $(redis_register_queues)"
}

echo_queue_job()
{
	#ready_jobs="$(etcd_queue_jobs)"
	#[ -n "$ready_jobs" ] || ready_jobs=nil 
	echo "ready_jobs: $(etcd_queue_jobs)"
}


get_all_queues ()
{
	while read line
	do
		{
			i=$(echo $line | awk '{print $1}')
			iii=$(echo $line | awk '{print $3}')
			j=$(redis-cli hget sched/host2queues $iii)
			echo $i pub_queues: $j 
		} &
	wait
	done < $registed_file
}

AuthUser() {
	# <= host_owner
	
	cur_user=$(whoami)

	[ "dewan" == "$cur_user" -o "root" == "$cur_user" ] && return
	
	[[ "$host_owner" =~ "$cur_user" ]] && return
	
	echo "Auth failed, check host_owner, please @lab_maintainer."
	return	
}

KnownHostHandel() {
	# <= host_ip
	sed -i "/$host_ip/d" ${HOME}/.ssh/known_hosts
}

CopySshId() {
	# <= host_ip
	# <= passwd_file

	[ -f $passwd_file ] || return	
	
	local tbox_passwd=$(cat $passwd_file)

	expect << EOF
	set timeout 5
	spawn ssh-copy-id -o StrictHostKeyChecking=no root@${host_ip} 
	expect "*assword" {send "${tbox_passwd}\r"}
	expect eof
EOF
}

SshCheck() {
	# <= host_ip
	# command: nc

	[ "$host_ip" = "null" ] && {
		echo no host ip, please check!
		exit
	}
	[ -z $host_ip ] && {
	
		echo "host_ip is null, please check!"
		exit
	}
	
	if command -v nc > /dev/null ; then
		nc -z $host_ip 22 || {
			echo "testbox's ssh-port not listen! "
			exit
		}
	fi
}

SshCmd() {
	# <= host_ip
	ssh -o StrictHostKeyChecking=no root@$host_ip "$@"
}

scp_cmd (){
	scp $1 root@$host_ip:/root
	exit
}

IbmcReset() {
	# <= host_num
	cur_user=$(whoami)
	if [ "dewan" = $cur_user ] ; then
		ssh -p 2022 ibmc-mgnt  "ibmcOper reboot $host_num"
	else
		ssh -p 2022 $USER@ibmc-mgnt  "ibmcOper reboot $host_num"
	fi
}

IbmcSetPXE() {
	# <= host_num
	cur_user=$(whoami)
	if [ "dewan" = $cur_user ] ; then
		ssh -p 2022 ibmc-mgnt  "ibmcOper bootpxe $host_num"
	else
		echo "Perrmisson Denied!"
#		ssh -p 2022 $USER@ibmc-mgnt  "ibmcOper bootpxe $host_num"
	fi
}

IbmcSetDisk() {
	# <= host_num
	cur_user=$(whoami)
	if [ "dewan" = $cur_user ] ; then
		ssh -p 2022 ibmc-mgnt  "ibmcOper bootdisk $host_num"
	else
		echo "Perrmisson Denied!"
#		ssh -p 2022 $USER@ibmc-mgnt  "ibmcOper bootdisk $host_num"
	fi
}


ViewSerialLog() {
	# <= host_name
	# <= serial_log_dir
	ssh -p 2022 ibmc-mgnt "tail -n 30 -f $serial_log_dir/$host_name"
}

DashboardActive() {
	active_file=/tmp/active.list_lstbox
	[ -f $active_file ] && echo "" > $active_file
	chmod 666 $active_file >/dev/null 2>&1

	while read line
	do
		i=$(echo $line | awk '{print $1}')
		hostname=$(echo $line | awk '{print $3}')
		echo "$i $hostname" >> $active_file
		job_info=$(redis-cli hget sched/tbox_wtmp ${hostname})
		echo $job_info >> $active_file

	done < $registed_file
	
	total=$(cat /etc/mac2host | wc -l)
	run_num=$(grep running $active_file | wc -l)
	reboot_num=$(grep rebooting $active_file | wc -l)
	request_num=$(grep requesting $active_file |wc -l)
	boot_num=$(grep booting $active_file | wc -l)

	echo -e "total: $total\tother: $((total - run_num - reboot_num - request_num - boot_num))"
	echo -e "running: $run_num\trebooting: $reboot_num\trequesting: $request_num\tbooting: $boot_num"
}

get_all_testboxes () {
	 redis-cli hgetall "sched/mac2host" | grep -E "^taishan.*a[0-9]+$|^2288.*b[0-9]+$" | sort -n | sort -u

}

get_ready_testboxes ()
{
	curl 172.168.131.2:20021/active_testbox | jq
}

DashboardJobs() {
	jobs_file=/tmp/jobs.list_lstbox
	[ -f $jobs_file ] && echo "" > $jobs_file
	chmod 666 $jobs_file >/dev/null 2>&1
	cp $active_file ${HOME}/active.list_lstbox
	for hostname in $(cat $registed_file | awk '{print $3}')
	do
		job_info=$(redis-cli hget sched/tbox_wtmp ${hostname}| sed 's/{//' | sed 's/}//' | sed 's/,/\n/g')
		job_id=$(echo "$job_info" | grep job_id | awk -F "\"" '{print $4}')
		[ -n "$job_id" ] || continue

		{	
			job_name=$(es-find id="$job_id" | grep \"suite\" | awk -F'"' '{print $4}')
			j=$(echo $job_name | awk '{print $1}')
			job_user=$(es-find id="$job_id" | grep \"my_account\" | awk -F'"' '{print $4}')
			echo $j $job_user >> $jobs_file
			
			sed -i "s|$hostname|$hostname $j $job_user|" ${HOME}/active.list_lstbox
		} &
	done
	wait
	
	echo "Detail:"
	sort $jobs_file | uniq -c | sort -nr > /tmp/tmpfile_lstbox
	chmod 666 /tmp/tmpfile_lstbox >/dev/null 2>&1

#	while read line
#	do	
#		tmp1=$(echo $line | awk '{print $2,$3}')
#		tmp2=$(echo $line | awk '{print $1}')
#		[ -n "$tmp1" ] || continue
#		printf " %-20s %s\n" $tmp1 $tmp2
#	done < /tmp/tmpfile_lstbox
#	echo
#	echo "For more info, please see ~/active.list_lstbox"

	cat /tmp/tmpfile_lstbox
}

clean_ready_job()
{
	local opt
	read -p "this operator will del the hostname's ready job, please Input [Y/N]:" opt
	
	[ -n "$host_name" ] || return

	if [ "$opt" = "Y" -o "$opt" = "y" ]
	then
		etcdctl del --prefix "/queues/sched/ready/$host_name/"
	fi
}

register_mac2host()
{
	cd ~/private-cci/bin || {
		echo "Dir not found: ~/private-cci/bin"
		exit
	}	

	./register-hw-info -n $host_name -m $host_mac

#	redis-cli hgetall sched/mac2host | grep $host_name -B 1
}

unregister_redis()
{
	local mac res
	mac=$(echo "$host_mac" | tr : -)
	res=$(redis-cli hget sched/mac2host "$mac")

	if [ -n "$res" ] ; then
		redis-cli hdel sched/mac2host "$mac"
		redis-cli hdel sched/host2queues "$host_name"
	else
		echo "no register"
	fi
}

get_monitor_file()
{
	# func: $1 => job name
	# func: $2 => job id

	echo "$(find /srv/result/$1 -type f | grep "$2/$1$")"
}

monitor_result()
{
	# func: $1 => job name
	# func: $2 => job id

	[ -n "$1" ] || return
	[ -n "$2" ] || return

	local _job_name=$1
	local _monitor_id=$2
	
	while true
	do
		local _res_file="$(get_monitor_file "${_job_name}" "${_monitor_id}")"

		if [ -n "$_res_file" ] ; then
			echo done. >> $log
			echo "$host_name's result file is ok, scp to crystal:~/hosts/lab-z9/" >> $log
			cat $_res_file | jq . > /tmp/dewan/$host_name
			scp /tmp/dewan/$host_name crystal:~/hosts/lab-z9/$host_name
			
			[ $? -eq 0 ] && {
				echo succeed! >> $log
			}
			rm -f $log 
			exit
		else
			echo -n "." >> $log
			sleep 10
		fi
	done
}

submit_host_file()
{	
	log=~/tmp/.lstbox_for_host_info_$$
	echo "$(date)" > $log
	
	submit host-info.yaml testbox=$host_name >> $log
	sleep 1
	local monitor_id=$(tail -1 $log | awk -F\= '{print $2}')

	echo "========" >> $log
	echo start to monitor result file. >> $log 
	monitor_result host-info $monitor_id &
	tail -f $log
}


submit_boards_file()
{
	log=~/tmp/.lstbox_boards_$$
	echo "$(date)" > $log

	submit boards-scan.yaml testbox=$host_name >> $log
	sleep 1
	
	local _job_id=$(tail -1 $log | awk -F\= '{print $2}')
	echo "========" >> $log
	echo start to monitor result file. >> $log
	monitor_result boards-scan $_job_id &
	tail -f $log
}

borrow_testbox()
{
	submit $borrow_yaml testbox=$host_name	
}

#### main ####

[ $# -eq 0 ] && usage && exit

params=$@	
tbox_num=$1

echo $params | grep -qw "sh" && {
	
	Basic > /dev/null
	SshCheck
	KnownHostHandel > /dev/null
	CopySshId 1> /dev/null 2>&1
	shift
	shift
	SshCmd "$@" 
	
	exit
}

echo $params | grep -qw "scp" && {
	Basic > /dev/null
	SshCheck
	KnownHostHandel > /dev/null
	CopySshId 1> /dev/null 2>&1
	scp_cmd $3
} 

echo $params | grep -qw "reset" && {
	Basic > /dev/null
	IbmcReset
	exit
}

echo $params | grep -qw "bootpxe" && {
	Basic > /dev/null
	IbmcSetPXE
	exit
}

echo $params | grep -qw "bootdisk" && {
	Basic > /dev/null
	IbmcSetDisk
	exit
}

echo $params | grep -qw "cat" && {
	Basic > /dev/null
#	SshCheck
	ViewSerialLog
	exit
}

echo $params | grep -q "stat" && {
	DashboardActive
	echo
	DashboardJobs
	exit
}

echo $params | grep -q "queues" && {
	get_all_queues
	exit
}

echo $params | grep -q "list" && {
	get_all_testboxes
	exit
}

echo $params | grep -q "ready" && {
	get_ready_testboxes
	exit
}

echo $params | grep -q "clean" && {
	Basic > /dev/null
	clean_ready_job
	exit
}

echo $params | grep -qw "register" && {
	Basic > /dev/null
	register_mac2host
	exit
}

echo $params | grep -qw "unregister" && {
	Basic > /dev/null
	unregister_redis
	exit
}

echo $params | grep -qE "host-file|host-info" && {
	Basic > /dev/null
	submit_host_file
	exit
}

echo $params | grep -qE "boards-file|boards-scan" && {
	Basic > /dev/null
	submit_boards_file
	exit
}

echo $params | grep -q "borrow" && {
	Basic > /dev/null
#	echo $params | tr ' ' '\n' | grep borrow
	borrow_yaml=$(echo $params | tr ' ' '\n' | grep borrow)
	borrow_testbox $yaml
	exit
}

for ele in $params
do
	tbox_num=$ele
	#echo "## testbox info ##"
	Basic
	echo_register_queues
	echo_queue_job
	echo
done

#} 	

